|
1
|
|
|
require('dotenv').config() |
|
2
|
|
|
const PKG = require('../../package.json') // so we can get the version of the project |
|
3
|
|
|
const BINPATH = './node_modules/nightwatch/bin/' // change if required. |
|
4
|
|
|
const SCREENSHOT_PATH = './node_modules/nightwatch/screenshots/' + PKG.version + '/' |
|
5
|
|
|
|
|
6
|
|
|
const config = { // we use a nightwatch.conf.js file so we can include comments and helper functions |
|
7
|
|
|
'src_folders': [ |
|
8
|
|
|
'./test/functional' // we use '/test' as the name of our test directory by default. So 'test/e2e' for 'e2e'. |
|
9
|
|
|
], |
|
10
|
|
|
'output_folder': './node_modules/nightwatch/reports', // reports (test outcome) output by Nightwatch |
|
11
|
|
|
'selenium': { |
|
12
|
|
|
'start_process': true, |
|
13
|
|
|
'server_path': BINPATH + 'selenium.jar', // downloaded by selenium-download module (see below) |
|
14
|
|
|
'log_path': '', |
|
15
|
|
|
'host': '127.0.0.1', |
|
16
|
|
|
'port': 4444, |
|
17
|
|
|
'cli_args': { |
|
18
|
|
|
'webdriver.chrome.driver': BINPATH + 'chromedriver' // also downloaded by selenium-download |
|
19
|
|
|
} |
|
20
|
|
|
}, |
|
21
|
|
|
'test_workers': {'enabled': true, 'workers': 'auto'}, // perform tests in parallel where possible |
|
22
|
|
|
'test_settings': { |
|
23
|
|
|
'default': { |
|
24
|
|
|
'launch_url': 'http://localhost', // we're testing a Public or "staging" site on Saucelabs |
|
25
|
|
|
'selenium_port': 80, |
|
26
|
|
|
'selenium_host': 'ondemand.saucelabs.com', |
|
27
|
|
|
'silent': true, |
|
28
|
|
|
'screenshots': { |
|
29
|
|
|
'enabled': true, // save screenshots to this directory (excluded by .gitignore) |
|
30
|
|
|
'path': SCREENSHOT_PATH |
|
31
|
|
|
}, |
|
32
|
|
|
/* eslint-disable no-template-curly-in-string */ |
|
33
|
|
|
'username': '${SAUCE_USERNAME}', // if you want to use Saucelabs remember to |
|
34
|
|
|
'access_key': '${SAUCE_ACCESS_KEY}', // export your environment variables (see readme) |
|
35
|
|
|
'globals': { |
|
36
|
|
|
'waitForConditionTimeout': 10000 // wait for content on the page before continuing |
|
37
|
|
|
} |
|
38
|
|
|
}, |
|
39
|
|
|
'local': { |
|
40
|
|
|
'launch_url': 'http://localhost', |
|
41
|
|
|
'selenium_port': 4444, |
|
42
|
|
|
'selenium_host': '127.0.0.1', |
|
43
|
|
|
'silent': true, |
|
44
|
|
|
'screenshots': { |
|
45
|
|
|
'enabled': true, // save screenshots taken here |
|
46
|
|
|
'path': SCREENSHOT_PATH |
|
47
|
|
|
}, // this allows us to control the |
|
48
|
|
|
'globals': { |
|
49
|
|
|
'waitForConditionTimeout': 15000 // on localhost sometimes internet is slow so wait... |
|
50
|
|
|
}, |
|
51
|
|
|
'desiredCapabilities': { |
|
52
|
|
|
'browserName': 'chrome', |
|
53
|
|
|
'chromeOptions': { |
|
54
|
|
|
'args': [ |
|
55
|
|
|
`Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 |
|
56
|
|
|
(KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3`, |
|
57
|
|
|
'--window-size=640,1136' // iphone 5 |
|
58
|
|
|
] |
|
59
|
|
|
}, |
|
60
|
|
|
'javascriptEnabled': true, |
|
61
|
|
|
'acceptSslCerts': true |
|
62
|
|
|
} |
|
63
|
|
|
}, |
|
64
|
|
|
'chrome': { // your local Chrome browser (chromedriver) |
|
65
|
|
|
'desiredCapabilities': { |
|
66
|
|
|
'browserName': 'chrome', |
|
67
|
|
|
'javascriptEnabled': true, |
|
68
|
|
|
'acceptSslCerts': true |
|
69
|
|
|
} |
|
70
|
|
|
}, |
|
71
|
|
|
'chromemac': { // browsers used on saucelabs: |
|
72
|
|
|
'desiredCapabilities': { |
|
73
|
|
|
'browserName': 'chrome', |
|
74
|
|
|
'platform': 'OS X 10.11', |
|
75
|
|
|
'version': '47' |
|
76
|
|
|
} |
|
77
|
|
|
}, |
|
78
|
|
|
'ie11': { |
|
79
|
|
|
'desiredCapabilities': { |
|
80
|
|
|
'browserName': 'internet explorer', |
|
81
|
|
|
'platform': 'Windows 10', |
|
82
|
|
|
'version': '11.0' |
|
83
|
|
|
} |
|
84
|
|
|
}, |
|
85
|
|
|
'firefox': { |
|
86
|
|
|
'desiredCapabilities': { |
|
87
|
|
|
'platform': 'XP', |
|
88
|
|
|
'browserName': 'firefox', |
|
89
|
|
|
'version': '33' |
|
90
|
|
|
} |
|
91
|
|
|
}, |
|
92
|
|
|
'internet_explorer_10': { |
|
93
|
|
|
'desiredCapabilities': { |
|
94
|
|
|
'platform': 'Windows 7', |
|
95
|
|
|
'browserName': 'internet explorer', |
|
96
|
|
|
'version': '10' |
|
97
|
|
|
} |
|
98
|
|
|
}, |
|
99
|
|
|
'android_s4_emulator': { |
|
100
|
|
|
'desiredCapabilities': { |
|
101
|
|
|
'browserName': 'android', |
|
102
|
|
|
'deviceOrientation': 'portrait', |
|
103
|
|
|
'deviceName': 'Samsung Galaxy S4 Emulator', |
|
104
|
|
|
'version': '4.4' |
|
105
|
|
|
} |
|
106
|
|
|
}, |
|
107
|
|
|
'iphone_6_simulator': { |
|
108
|
|
|
'desiredCapabilities': { |
|
109
|
|
|
'browserName': 'iPhone', |
|
110
|
|
|
'deviceOrientation': 'portrait', |
|
111
|
|
|
'deviceName': 'iPhone 6', |
|
112
|
|
|
'platform': 'OSX 10.10', |
|
113
|
|
|
'version': '8.4' |
|
114
|
|
|
} |
|
115
|
|
|
} |
|
116
|
|
|
}, |
|
117
|
|
|
'local': { |
|
118
|
|
|
'launch_url': 'http://localhost:3000/', |
|
119
|
|
|
'selenium_port': 4444, |
|
120
|
|
|
'selenium_host': '127.0.0.1', |
|
121
|
|
|
'silent': false, |
|
122
|
|
|
'screenshots': { |
|
123
|
|
|
'enabled': true, // if you want to keep screenshots |
|
124
|
|
|
'path': './screenshots' // save screenshots here |
|
125
|
|
|
}, |
|
126
|
|
|
'globals': { |
|
127
|
|
|
'waitForConditionTimeout': 5000 // sometimes internet is slow so wait. |
|
128
|
|
|
}, |
|
129
|
|
|
'desiredCapabilities': { // use Chrome as the default browser for tests |
|
130
|
|
|
'browserName': 'chrome' |
|
131
|
|
|
} |
|
132
|
|
|
}, |
|
133
|
|
|
'chrome': { |
|
134
|
|
|
'desiredCapabilities': { |
|
135
|
|
|
'browserName': 'chrome', |
|
136
|
|
|
'javascriptEnabled': true // turn off to test progressive enhancement |
|
137
|
|
|
} |
|
138
|
|
|
} |
|
139
|
|
|
} |
|
140
|
|
|
module.exports = config |
|
141
|
|
|
|
|
142
|
|
|
/** |
|
143
|
|
|
* selenium-download does exactly what it's name suggests; |
|
144
|
|
|
* downloads (or updates) the version of Selenium (& chromedriver) |
|
145
|
|
|
* on your localhost where it will be used by Nightwatch. |
|
146
|
|
|
*/ |
|
147
|
|
|
require('fs').stat(BINPATH + 'selenium.jar', function (err, stat) { // got it? |
|
148
|
|
|
if (err || !stat || stat.size < 1) { |
|
149
|
|
|
require('selenium-download').ensure(BINPATH, function (error) { |
|
150
|
|
|
if (error) throw new Error(error) // no point continuing so exit! |
|
|
|
|
|
|
151
|
|
|
console.log('✔ Selenium & Chromedriver downloaded to:', BINPATH) |
|
|
|
|
|
|
152
|
|
|
}) |
|
153
|
|
|
} |
|
154
|
|
|
}) |
|
155
|
|
|
|
|
156
|
|
|
function padLeft (count) { // theregister.co.uk/2016/03/23/npm_left_pad_chaos/ |
|
157
|
|
|
return count < 10 ? '0' + count : count.toString() |
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
var FILECOUNT = 0 // "global" screenshot file count |
|
161
|
|
|
/** |
|
162
|
|
|
* The default is to save screenshots to the root of your project even though |
|
163
|
|
|
* there is a screenshots path in the config object above! ... so we need a |
|
164
|
|
|
* function that returns the correct path for storing our screenshots. |
|
165
|
|
|
* While we're at it, we are adding some meta-data to the filename, specifically |
|
166
|
|
|
* the Platform/Browser where the test was run and the test (file) name. |
|
167
|
|
|
*/ |
|
168
|
|
|
function imgpath (browser) { |
|
169
|
|
|
var a = browser.options.desiredCapabilities |
|
170
|
|
|
var meta = [a.platform] |
|
171
|
|
|
meta.push(a.browserName ? a.browserName : 'any') |
|
172
|
|
|
meta.push(a.version ? a.version : 'any') |
|
173
|
|
|
meta.push(a.name) // this is the test filename so always exists. |
|
174
|
|
|
var metadata = meta.join('~').toLowerCase().replace(/ /g, '') |
|
175
|
|
|
return SCREENSHOT_PATH + metadata + '_' + padLeft(FILECOUNT++) + '_' |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
module.exports.imgpath = imgpath |
|
179
|
|
|
module.exports.SCREENSHOT_PATH = SCREENSHOT_PATH |
|
180
|
|
|
|
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.